<?php
 /**
  * @version   $Id$
  * @author    RocketTheme http://www.rockettheme.com
  * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
  * @license   http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
  */

class RokCommon_Doctrine_Record extends Doctrine_Record
{
    /**
     * @return void
     */
    public function setUp()
    {
        parent::setUp();

        $classname = get_class($this) . "Filter";
        if (class_exists($classname, true) && is_subclass_of($classname, 'Doctrine_Record_Filter')) {
            $this->unshiftFilter(new $classname());
        }
    }

    public function addField($name, $value)
    {
        $this->$name = $value;
    }

    /**
     * returns the record representation as an array
     *
     * @link http://www.doctrine-project.org/documentation/manual/1_1/en/working-with-models
     * @param boolean $deep         whether to include relations
     * @param boolean $prefixKey    not used
     * @return array
     */
    public function toJsonableArray($deep = true, $prefixKey = false)
    {
        if ($this->_state == self::STATE_LOCKED || $this->_state == self::STATE_TLOCKED) {
            return false;
        }

        $stateBeforeLock = $this->_state;
        $this->_state = $this->exists() ? self::STATE_LOCKED : self::STATE_TLOCKED;

        $a = array();

        foreach ($this as $column => $value) {
            if ($value === self::$_null || is_object($value)) {
                $value = null;
            }

            $columnValue = $this->get($column, false);

            if ($columnValue instanceof Doctrine_Record) {
                $a[$column] = $columnValue->getIncremented();
            } else {
                $a[$column] = $columnValue;
            }
        }

        if ($this->_table->getIdentifierType() == Doctrine_Core::IDENTIFIER_AUTOINC) {
            $i = $this->_table->getIdentifier();
            $a[$i] = $this->getIncremented();
        }

        if ($deep) {
            foreach ($this->_references as $key => $relation) {
                if (!$relation instanceof Doctrine_Null) {
                    $a[$key] = $relation->toArray($deep, $prefixKey);
                    $link = $this->getTable()->getRelation($key)->getForeignColumnName();
                    if ($relation instanceof Doctrine_Record) {
                        unset($a[$key][$link]);
                    }
                    elseif ($relation instanceof Doctrine_Collection)
                    {
                        foreach ($a[$key] as $relkey => $relation_item) {
                            unset($relation_item[$link]);
                            $a[$key][$relkey] = $relation_item;
                        }
                    }

                }
            }
        }

        // [FIX] Prevent mapped Doctrine_Records from being displayed fully
        foreach ($this->_values as $key => $value) {
            $a[$key] = ($value instanceof Doctrine_Record || $value instanceof Doctrine_Collection)
                    ? $value->toArray($deep, $prefixKey) : $value;
        }

        $this->_state = $stateBeforeLock;

        return $a;
    }


    /**
     * Contains fix for filterget performace issue
     *
     * @throws Doctrine_Exception|Doctrine_Table_Exception
     * @param  $fieldName
     * @param bool $load
     * @return null
     */
    protected function _get($fieldName, $load = true)
    {
        $value = self::$_null;

        if (array_key_exists($fieldName, $this->_values)) {
            return $this->_values[$fieldName];
        }

        if (array_key_exists($fieldName, $this->_data)) {
            // check if the value is the Doctrine_Null object located in self::$_null)
            if ($this->_data[$fieldName] === self::$_null && $load) {
                $this->load();
            }

            if ($this->_data[$fieldName] === self::$_null) {
                $value = null;
            } else {
                $value = $this->_data[$fieldName];
            }

            return $value;
        }

        if (isset($this->_references[$fieldName])) {
            if ($this->_references[$fieldName] === self::$_null) {
                return null;
            }
            return $this->_references[$fieldName];
        }

        $rel = $this->_table->getRelation($fieldName);
        if ($load && $rel !== false) {
            $this->_references[$fieldName] = $rel->fetchRelatedFor($this);
        }
        elseif ($rel === false)
        {
            $success = false;
            $value = null;
            foreach ($this->_table->getFilters() as $filter) {
                try {
                    $value = $filter->filterGet($this, $fieldName);
                    $success = true;
                    break;
                } catch (Doctrine_Exception $e) {
                }
            }
            if ($success) {
                return $value;
            } else {
                throw $e;
            }
        }
        else {
            $this->_references[$fieldName] = null;
        }

        if (!isset($this->_references[$fieldName])) {
            if ($load) {
                $rel = $this->_table->getRelation($fieldName);
                $this->_references[$fieldName] = $rel->fetchRelatedFor($this);
            } else {
                $this->_references[$fieldName] = null;
            }
        }

        if ($this->_references[$fieldName] === self::$_null) {
            return null;
        }


        return $this->_references[$fieldName];
    }

}
